package com.sigmazero13.bgjeeves;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.sigmazero13.bgjeeves.GameTimerService.LocalBinder;
import com.sigmazero13.bgjeeves.db.UtilDbHelper;
import com.sigmazero13.bgjeeves.model.GameInfo;
import com.sigmazero13.bgjeeves.model.GamePlayerInfo;
import com.sigmazero13.bgjeeves.widgets.MultiPlayerEntry;
import com.sigmazero13.bgjeeves.widgets.PlayerEntryView;

public class GameTimerView extends Activity implements OnClickListener, android.content.DialogInterface.OnClickListener, GameListPickerDialog.OnGamePickedListener {
	private final int GAME_DIALOG_ID = 1;
	
	private GameTimerService mService;
	boolean mBound = false;
	private Button startStopButton;
	private Button endButton;
	private Button randomOrderButton;
	private Button randomTeamButton;
	private Timer refreshTimer;
	private TextView timerText;
	private GameInfo pickedGame = new GameInfo();
	private TextView pickedGameText;
	private List<GameInfo> games;
	private AlertDialog endDialog;
	private MultiPlayerEntry playerView;
	private UtilDbHelper dbHelper;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.game_timer);
		
		Bundle bundle = getIntent().getExtras();
		int gameId = 0;
		if (bundle != null) {
			gameId = bundle.getInt("game_id", 0);
		}
		
		games = ((BoardGameUtilsApp)GameTimerView.this.getApplication()).getDbHelper().selectAllGames(); 
		
		pickedGameText = (TextView) findViewById(R.id.timer_pick_game_text);
		
		pickedGameText.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				showDialog(GAME_DIALOG_ID);
			}
		});
		
		timerText = (TextView)findViewById(R.id.timer_text);
		
		startStopButton = (Button)findViewById(R.id.button_timer_start_stop);
		startStopButton.setOnClickListener(this);
		
		endDialog = new AlertDialog.Builder(this)
			.setMessage(R.string.end_dialog_message)
			.setCancelable(true)
			.setPositiveButton(R.string.end_dialog_record, this)
			.setNeutralButton(R.string.end_dialog_endonly, this)
			.setNegativeButton(R.string.end_dialog_cancel, this)
			.create();
		
		endButton = (Button)findViewById(R.id.button_timer_end);
		endButton.setOnClickListener(this);
		
		playerView = (MultiPlayerEntry)findViewById(R.id.player_list);
		
		randomOrderButton = (Button)findViewById(R.id.button_randomize_player_order);
		randomOrderButton.setOnClickListener(this);
		
		randomTeamButton = (Button)findViewById(R.id.button_randomize_teams);
		randomTeamButton.setOnClickListener(this);
		
		dbHelper = ((BoardGameUtilsApp)getApplication()).getDbHelper();
		playerView.setPlayerList(dbHelper.getPlayerNames());
		playerView.setUsernameList(dbHelper.getPlayerUsernames());
		playerView.setTeamList(dbHelper.getTeamsForGame(gameId));
		
		if (gameId > 0) {
			setGame(gameId);
		} else {
			setGame(games.get(0).getGameId());
		}
		
	}
	
	
	@Override
	protected void onStart() {
		super.onStart();
		Intent intent = new Intent(this, GameTimerService.class);
		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
		
		refreshTimer = new Timer("GameTimer");
		
		final Runnable updateTask = new Runnable() {
			@Override
			public void run() {
				updateTimerText();
			}
		};
		
		refreshTimer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				runOnUiThread(updateTask);
			}
		}, 1000, 1000);
	}
	
	
	@Override
	protected void onStop() {
		super.onPause();
		try {
			unbindService(mConnection);
		} catch (Exception e) {
			Log.d("GameTimerView.onPause", e.getMessage());
		}
		refreshTimer.cancel();
		refreshTimer.purge();
		refreshTimer = null;
	}
	
	
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		ArrayList<GamePlayerInfo> players = new ArrayList<GamePlayerInfo>(playerView.getAllPlayers());
		
		outState.putParcelableArrayList("playerList", players);
	}
	
	@Override
	public void onRestoreInstanceState(Bundle inState) {
		super.onRestoreInstanceState(inState);
		
		ArrayList<GamePlayerInfo> players = inState.getParcelableArrayList("playerList");
		
		playerView.setPlayerInfo(players);
	}
	
	
	@Override
	public void onClick(View v) {
		if (v.equals(startStopButton)) {
			toggleTimer();
		} else if (v.equals(endButton)) {
			endGame();
		} else if (v.equals(randomOrderButton)) {
			randomizeOrder();
		} else if (v.equals(randomTeamButton)) {
			randomizeTeams();
		}
	}
	
	
	@Override
	public void onClick(DialogInterface dialog, int which) {
		switch (which) {
		case DialogInterface.BUTTON_POSITIVE:
			endAndRecord();
			break;
		case DialogInterface.BUTTON_NEUTRAL:
			mService.resetTimer();
			startStopButton.setText(R.string.start_timer);
			break;
		default:
			break;
		}
	}
	
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case GAME_DIALOG_ID:
			return new GameListPickerDialog(this, games, this);
		}
		return null;
	}
	
	
	@Override
	public void onGamePicked(GameInfo game) {
		pickedGameText.setText(game.getName());
		this.pickedGame = game;
		updateAutocompletes(game);
	}
	
	
	private void updateAutocompletes(GameInfo game) {
		List<String> teams = null;
		if (game != null) {
			teams = dbHelper.getTeamsForGame(game.getGameId());
		}
		playerView.setTeamList(teams);
	}
	
	
	private ServiceConnection mConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName className, IBinder service) {
			LocalBinder binder = (LocalBinder) service;
			mService = binder.getService();
			mBound = true;
		}
		
		@Override
		public void onServiceDisconnected(ComponentName className) {
			mBound = false;
		}
	};
	
	
	private void setGame(int gameId) {
		for (GameInfo game : games) {
			if (game.getGameId() == gameId) {
				this.onGamePicked(game);
			}
		}
	}
	
	
	private void updateTimerText() {
		long curTime = mService.getElapsedSeconds();
		long seconds = curTime % 60;
		long minutes = (curTime / 60) % 60;
		long hours = curTime / 3600;
		
		timerText.setText(String.format("%02d:%02d:%02d",hours,minutes,seconds));
	}
	
	
	private void toggleTimer() {
		if (mBound) {
			Integer newText = 0;
			mService.setGameName(pickedGame.getName());
			
			if (mService.isRunning()) {
				mService.stopTimer();
				if (mService.getElapsedSeconds() > 0) {
					newText = R.string.continue_timer;
				} else {
					newText = R.string.start_timer;
				}
			} else {
				mService.startTimer();
				newText = R.string.pause_timer;
			}
			
			startStopButton.setText(newText);
		}
	}
	
	private void endGame() {
		if (mBound) {
			if (mService.getElapsedSeconds() == 0) {
				Toast.makeText(GameTimerView.this, "The game has not started!", Toast.LENGTH_SHORT).show();
			} else {
				endDialog.show();
			}
		}
	}
	
	private void endAndRecord() {
		long minutes = mService.getElapsedSeconds()/60;
		mService.resetTimer();
		startStopButton.setText(R.string.start_timer);
		Intent i = new Intent();
		i.putExtra("game_id", pickedGame.getGameId());
		i.putExtra("game_length", minutes);
		
		ArrayList<GamePlayerInfo> players = new ArrayList<GamePlayerInfo>(playerView.getAllPlayers());
		i.putParcelableArrayListExtra("players", players);
		setResult(RESULT_OK, i);
		finish();
	}
	
	private void randomizeOrder() {
		List<GamePlayerInfo> players = playerView.getAllPlayers();
		if (players.size() < 1) {
			Toast.makeText(this, R.string.randomize_not_enough_players, Toast.LENGTH_LONG).show();
			return;
		}
		Collections.shuffle(players);
		for (int i = 0; i < players.size(); i++) {
			players.get(i).setStartingPos(i+1);
		}
		playerView.setPlayerInfo(players);
		String firstPlayer = getResources().getString(R.string.first_player, players.get(0).getName());
				
		Toast.makeText(this, firstPlayer, Toast.LENGTH_SHORT).show();
	}
	
	private void randomizeTeams() {
		Integer gameId = pickedGame.getGameId();
		List<String> teams = ((BoardGameUtilsApp)getApplication()).getDbHelper().getTeamsForGame(gameId);
		List<PlayerEntryView> playerViews = playerView.getAllInputs();
		
		if (teams.size() < playerViews.size()) {
			Toast.makeText(this, R.string.randomize_not_enough_teams, Toast.LENGTH_LONG).show();
			return;
		}
		
		Collections.shuffle(teams);
		StringBuilder teamResults = new StringBuilder();
		for (int i = 0; i < playerViews.size(); i++) {
			List<String> oneTeam = new ArrayList<String>();
			oneTeam.add(teams.get(i));
			playerViews.get(i).setTeams(oneTeam);
			teamResults.append(playerViews.get(i).getPlayerName() + ": " + teams.get(i) + "\n");
		}
		if (teamResults.length() > 0) {
			teamResults.setLength(teamResults.length()-1);
			Toast.makeText(this, teamResults.toString(), Toast.LENGTH_LONG).show();
		} else {
			Toast.makeText(this, "Random Teams requires at least one player to be entered...", Toast.LENGTH_SHORT).show();
		}
	}
	
}
